/*
 * Class NetReader
 * Created on 13/04/2005
 */
package pATT.bNEdit.base;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.Vector;

/**
 * @author Marcelo
 *
 */
@SuppressWarnings("unchecked")
public class Xml03Reader implements Serializable {

    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private RedBayes bayesNet;

    /**
     * @param bayesNet
     */
    public Xml03Reader(RedBayes bayesNet) {
        this.bayesNet = bayesNet;
    }

    /**
     * @return Returns the bayesNet.
     */
    public RedBayes getBayesNet() {
        return bayesNet;
    }

    public void load(String nombreArch){
      try{

        BufferedReader reader = new BufferedReader(new FileReader(nombreArch));
        String s=new String();
        boolean seguir=true;

        while(seguir){
            String t=reader.readLine();
            if(t==null)
                seguir=false;
            else
                s=s + t;
        }

        this.loadFromString(s);

      }catch(IOException e){
        System.out.println("Error leyendo archivo: " + e.getMessage());
//        System.exit(0);
      }
    }

    public void loadFromString(String xml){

            String nombre = xml.substring(xml.indexOf("<NAME>")+6,xml.indexOf("</NAME>"));
            getBayesNet().setNombre(nombre);
            String variables=xml.substring(xml.indexOf("<VARIABLE"), xml.lastIndexOf("</VARIABLE>")+11);
            String definiciones=xml.substring(xml.indexOf("<DEFINITION>"), xml.lastIndexOf("</DEFINITION>")+13);
       //     String expdef=xml.substring(xml.indexOf("<EXPERIENCE DEFINITION>"), xml.lastIndexOf("</EXPERIENCE DEFINITION>")+24);

            cargarVariables(variables);
            cargarArcos(definiciones);
            cargarValoresProb(definiciones);
      //      cargarValoresExp(expdef);

    }


	public void cargarVariables(String cad){
        String cadena= new String(cad);
        int cantVar=cantidadTokens(cadena,"</VARIABLE>");
        //para guardar la cantidad de estados de cada variable
        //variables=new int[cantVar];
        for(int i=0 ; i < cantVar; i++)
        {   String variable=cadena.substring(cadena.indexOf("<VARIABLE"),cadena.indexOf("</VARIABLE"));
            String nomVar=cadena.substring(cadena.indexOf("<NAME>")+6,cadena.indexOf("</NAME>"));
            getBayesNet().addNodo(nomVar);
            String posicion =
                cadena.substring(cadena.indexOf("<PROPERTY>")+10,
                                 cadena.indexOf("</PROPERTY>"));
            posicion = posicion.substring(posicion.indexOf("(")+1,
                                          posicion.indexOf(")"));
            String posXs = posicion.substring(0,posicion.indexOf(","));
            String posYs = posicion.substring(posicion.indexOf(",")+1);
            int posX = Integer.parseInt(posXs.replaceAll(" ",""));
            int posY = Integer.parseInt(posYs.replaceAll(" ",""));
            getBayesNet().getNodo(nomVar).setPosicion(posX,posY);
            int cantEst=cantidadTokens(variable,"</OUTCOME>");
            //variables[i]=cantEst;
            Vector estados=new Vector();
            for(int j=0 ; j < cantEst; j++){
                String est=variable.substring(variable.indexOf("<OUTCOME>")+9,variable.indexOf("</OUTCOME>"));
                estados.addElement(est);
                variable=variable.substring(variable.indexOf("</OUTCOME>")+10);
            };
            getBayesNet().getNodo(nomVar).setEstados(estados);
            cadena=cadena.substring(cadena.indexOf("</VARIABLE>")+11);
        }
      }
    public void cargarArcos(String cad){
        String cadena= new String(cad);
        int cantVar=cantidadTokens(cadena,"</DEFINITION>");
        //para guardar la cantidad de estados de cada variable
        for(int i=0 ; i < cantVar; i++)
        {   String variable=cadena.substring(cadena.indexOf("<DEFINITION"),cadena.indexOf("</DEFINITION>"));
            //Obtengo el nombre de la variable
            String nomVar=cadena.substring(cadena.indexOf("<FOR>")+5,cadena.indexOf("</FOR>"));
            int cantPadres=cantidadTokens(variable,"</GIVEN>");
            //obtengo los padres de la variable
            for(int j=0 ; j < cantPadres; j++){
                String padre=variable.substring(variable.indexOf("<GIVEN>")+7,variable.indexOf("</GIVEN>"));
                getBayesNet().addArco(padre,nomVar);
                variable=variable.substring(variable.indexOf("</GIVEN>")+8);
            };
            cadena=cadena.substring(cadena.indexOf("</DEFINITION>")+13);
        }
      }

    public void cargarValoresProb(String cad){
        String cadena= new String(cad);
        int cantTablas=cantidadTokens(cadena,"</DEFINITION>");
        double[] valores;
        for(int i=0 ; i < cantTablas; i++)
        {   //String variable=cadena.substring(cadena.indexOf("<DEFINITION"),cadena.indexOf("</DEFINITION>"));
            String nomVar=cadena.substring(cadena.indexOf("<FOR>")+5,cadena.indexOf("</FOR>"));
            String tabla=cadena.substring(cadena.indexOf("<TABLE>")+ 8,cadena.indexOf("</TABLE>"));
            int cantValores=cantidadTokens(tabla," ");
            valores=new double[cantValores];
            for(int j=0 ; j < cantValores; j++){
                String valor=tabla.substring(0,tabla.indexOf(" "));
                Double v=new Double(valor);
                valores[j]=v.doubleValue();
                tabla=tabla.substring(tabla.indexOf(" ")+1);
            }
            Potencial p=getBayesNet().getNodo(nomVar).getProbabilidadOriginal();
            int CantEstados=getBayesNet().getNodo(nomVar).getEstados().size();
            int pos=0;
            //for(int k=0 ; k < variables[i] ; k++ ){
            for(int k=0 ; k < CantEstados ; k++ ){
               for(int h= k ; h < cantValores  ; h = h + CantEstados )
               {        p.set(pos,valores[h]);
                        pos++;
               }

            }
            cadena=cadena.substring(cadena.indexOf("</DEFINITION>")+13);
        }
      }

      public void cargarValoresExp(String cad){
        String cadena= new String(cad);
        int cantTablas=cantidadTokens(cadena,"</EXPERIENCE DEFINITION>");
        double[] valores;
        for(int i=0 ; i < cantTablas; i++)
        {   //String variable=cadena.substring(cadena.indexOf("<EXPERIENCE DEFINITION"),cadena.indexOf("</EXPERIENCE DEFINITION>"));
            String nomVar=cadena.substring(cadena.indexOf("<FOR>")+5,cadena.indexOf("</FOR>"));
            String tabla=cadena.substring(cadena.indexOf("<TABLE>")+ 8,cadena.indexOf("</TABLE>"));
            int cantValores=cantidadTokens(tabla," ");
            valores=new double[cantValores];
            for(int j=0 ; j < cantValores; j++){
                String valor=tabla.substring(0,tabla.indexOf(" "));
                Double v=new Double(valor);
                valores[j]=v.doubleValue();
                tabla=tabla.substring(tabla.indexOf(" ")+1);
            }
            getBayesNet().getNodo(nomVar).addExperienceTable();
            ExperienceTable exp= getBayesNet().getNodo(nomVar).getExperienceTable();
            for (int k=0; k<cantValores; k++ ){
              exp.set(k, valores[k]);
            }
            cadena=cadena.substring(cadena.indexOf("</EXPERIENCE DEFINITION>")+24);
        }

      }
      private int cantidadTokens(String cad,String Tok){
          String cadena=new String(cad);
  		int cont=0;
  		int i=cadena.indexOf(Tok)+Tok.length();
          while(cadena.indexOf(Tok)!=-1){
  			cadena=cadena.substring(i);

          	i=cadena.indexOf(Tok)+Tok.length();
              cont++;
          }
          return cont;
        }
}
